home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i056: Ease, a language for writing sendmail.cf files, Part04/04
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: ksb@j.cc.purdue.edu
- Mod.sources: Volume 8, Issue 56
- Archive-name: ease/Part04
-
- [ A couple of things to note, here. First, watch out for the horribly
- long "usage" string -- I bet some compilers can't handle it (it should
- probably be an array of text lines, anyhow). Second, it would be
- great if someone converted this program to use getopt(3), and sent the
- changes on to the maintainers... --r$ ]
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # maketd
- mkdir maketd
- chdir maketd
- cat << \SHAR_EOF > Makefile
- # For a VAX
- DEFS= -DBSD4_2
- LDFLAGS=
-
- # For a PDP 11/70
- # DEFS= -DBSD2_9
- # LDFLAGS= -i
-
- INCLUDE=
- CFLAGS= -O ${DEFS} ${INCLUDE}
- DEST= /usr/new/bin
-
- SRC= abrv.c maketd.c misc.c nshpopen.c breakargs.c srtunq.c
- HDR= maketd.h abrv.h nshpopen.h srtunq.h
- OBJ= maketd.o abrv.o misc.o nshpopen.o breakargs.o srtunq.o
-
- all: maketd
-
- maketd: ${OBJ}
- ${CC} ${LDFLAGS} ${OBJ} -o maketd
-
- clean: FRC
- rm -f ${OBJ} maketd \#* *.bak core a.out
-
- depend: source
- maketd -a ${DEFS} ${INCLUDE} ${SRC}
-
- install: maketd
- install -s -m 0751 -o binary -g system maketd ${DEST}
-
- lint: source
- lint -hpx ${SRC}
-
- print: source
- lpr -p Makefile ${HDR} ${SRC}
-
- shar: source
- shar Makefile ${SRC} ${HDR} Manual
-
- source: Makefile ${SRC} ${HDR}
-
- spotless: clean
- rcsclean ${SRC} ${HDR} Makefile
-
- ${SRC} ${HDR}:
- co $@
-
- FRC:
-
- # a clever way to save a few more characters
- I=/usr/include/
- S=/usr/include/sys/
-
- # DO NOT DELETE THIS LINE - make depend DEPENDS ON IT
-
- abrv.o: $Ictype.h $Istdio.h abrv.c abrv.h maketd.h srtunq.h
-
- maketd.o: $Ictype.h $Imachine/machparam.h $Isignal.h $Istdio.h $Sdir.h \
- $Sfile.h $Sparam.h $Stypes.h abrv.h maketd.c maketd.h nshpopen.h \
- srtunq.h
-
- misc.o: $Istdio.h $Ssignal.h maketd.h misc.c
-
- nshpopen.o: $Isignal.h $Istdio.h nshpopen.c
-
- breakargs.o: $Istdio.h breakargs.c
-
- srtunq.o: $Istdio.h $Stypes.h srtunq.c srtunq.h
-
- # *** Do not add anything here - It will go away. ***
- SHAR_EOF
- if test 1371 -ne "`wc -c Makefile`"
- then
- echo shar: error transmitting Makefile '(should have been 1371 characters)'
- fi
- mkdir Manual
- chdir Manual
- cat << \SHAR_EOF > maketd.1l
- .TH MAKETD 1L "11 November 1985"
- .if n \{.de Q
- "\\$1"\\$2
- .\}
- .if t \{.de Q
- ``\\$1''\\$2
- .\}
- ..
- .SH NAME
- maketd \- make transitive dependencies
- .SH SYNOPSIS
- .B maketd
- [
- .I option(s)
- ]
- .I file(s)
- .SH DESCRIPTION
- .I Maketd
- computes dependencies for makefiles from sources introduced through
- include files.
- It generates lines like
- .Q "xx.o: e.h struct.h ../h/const.h ..." .
- It makes xx.o not only dependent on all files it includes,
- but also recursively on all files other files include.
- This is achieved by passing the source through the C preprocessor.
- .PP
- The directories used in the search for include files
- are identical to the ones used by the C compiler, because the
- C preprocessor is used.
- This also means that `#define's, `#ifdef's, etc. are evaluated.
- It may therefore be necessary to recompute the dependencies if
- any source has been changed, including the associated Makefile.
- .PP
- A typical application in a Makefile goes as follows:
- .nf
-
- INCL= \-I../include \-I../h
- CFLAGS= \-DPUCC \-DBSD4_2 ${INCL}
- SRC= a.c b.c c.c
-
- maketd: ${SRC}
- maketd \-a ${CFLAGS} ${SRC}
-
- # DO NOT DELETE THIS LINE \- make depend DEPENDS ON IT
-
- .fi
- The generated dependencies will be inserted after the `# DO NOT DELETE...'
- line.
- Everything after this line will go away through the editing
- process of the Makefile.
- If no such line exists, a line of the expected form will be emitted,
- followed by the dependencies.
- The default filename for the Makefile is `makefile'.
- If `makefile' does not exist, `Makefile' is used.
- The \-m and \-d options override this default action.
- Before it is edited, the Makefile will be saved in `Makefile.bak',
- overwritting any existing `Makefile.bak'.
- .PP
- Several options apply.
- If an option takes any arguments, all arguments follow the option
- directly, with no spaces.
- If spaces are required inside an argument to an option, then
- quotes must be used to prevent the shell from breaking up the
- argument.
- .TP
- .BI \-a
- Normally, dependencies on files in `/usr/include' are
- not included \- this option also includes dependencies on those files.
- .TP
- .BI \-b
- Generate dependencies for binaries rather than object files.
- This is equivelent to specifying a null suffix.
- The `.o' is stripped from the filename.
- .TP
- .BI \-d
- Instead of editing the Makefile, dependencies are written to standard
- output.
- The standard header and trailer, `# DO NOT...' are not emitted.
- .TP
- .BI \-f
- Force printing of header and trailer.
- Normally, these are suppresed when the output file is the standard
- output.
- .TP
- .BI \-h
- Print a set of oneline descriptions to the terminal and exit.
- .TP
- .BI \-m file
- Instead of editing `makefile' or `Makefile', the file named
- .I file
- is edited.
- .TP
- .BI \-nonlocalo
- Generate dependency paths that match the source paths given.
- .TP
- .BI \-o directory
- Normally dependencies are of the form
- .Q "a.o: ....." .
- This option generates dependencies of the form
- .Q "\fIdirectory\fP/a.o:...." ,
- which is useful for Makefiles which store the objects in
- a separate subdirectory.
- The name of the directory must not be empty.
- .TP
- .BI \-r
- Causes the dependencies for a single source file to be generated and
- replaced in the edited Makefile.
- .TP
- .BI \-s suffix
- Supply a suffix for the target.
- The suffix should start with a `.'.
- The target file name should have a suffix of some sort that
- is delimited by a `.' that is replaced by this suffix.
- .TP
- .BI \-t target
- Supply a new basename for the target.
- .TP
- .BI \-x
- Don't shorten include files.
- The default action is to replace various strings with abbreviations.
- The Makefile is scanned to see which single letter uppercase
- variables are set.
- These definitions are remembered.
- The pathnames `/usr/include' and `/usr/include/sys', along with any
- pathnames specified with \-I options are also used in abbreviations.
- Unused uppercase single letters are defined, printed to the Makefile,
- and used.
- .TP
- .BI \-v
- Be verbose.
- Extra output is directed to
- .I stderr.
- .TP
- .BI \-I...
- Specify a directory to search for include files.
- This option is passed to /lib/cpp, and thus behaves identically to
- the same option to `cc'.
- .TP
- .BI \-D...
- Specify a definition.
- This option is passed to /lib/cpp, and thus behaves identically to
- the same option to `cc'.
- .TP
- .BI \-U....
- Specify that a variable that should not be defined.
- This option is passed to /lib/cpp, and thus behaves identically to
- the same option to `cc'.
- .IR cc (1).
- .SH "AUTHOR"
- Stephan v. Bechtolsheim (the shell script) (Purdue CS)
- .br
- Stephen Uitti (the C version) (PUCC)
- .SH "SEE ALSO"
- make(1), cc(1)
- SHAR_EOF
- if test 4509 -ne "`wc -c maketd.1l`"
- then
- echo shar: error transmitting maketd.1l '(should have been 4509 characters)'
- fi
- cat << \SHAR_EOF > nshpopen.3l
- .TH NSHPOPEN 3 "local"
- .SH NAME
- nshpopen, nshpclose \- initiate I/O to/from a process
- .SH SYNOPSIS
- .B #include <stdio.h>
- .PP
- .SM
- .B FILE
- .B *nshpopen(command, type)
- .br
- .B char *command, *type;
- .PP
- .B nshpclose(stream)
- .br
- .SM
- .B FILE
- .B *stream;
- .SH DESCRIPTION
- The arguments to
- .I nshpopen
- are pointers to null-terminated strings containing respectively
- a shell command line and an I/O mode, either "r" for reading or
- "w" for writing.
- It creates a pipe between the calling process and the command
- to be executed.
- The value returned is a stream pointer that can be used (as
- appropriate) to write to the standard input of the command or
- read from its standard output.
- .PP
- A stream opened by
- .I nshpopen
- should be closed by
- .IR nshpclose ,
- which waits for the associated process to terminate
- and returns the exit status of the command.
- .PP
- Because open files are shared, a type "r" command may be used
- as an input filter, and a type "w" as an output filter.
- .PP
- .I Nshpopen
- breaks up the
- .I command
- argument string at spaces and tabs for the child process.
- However, it does not invoke a shell, and does not
- attempt any shell shell meta character parsing.
- In particular, quoted white space will still cause argument seperation.
- By avoiding calling a shell, pipe creation is a great deal quicker.
- Also, by avoiding the (rather complicated) shell meta character
- parsing, some types of bugs may be avoided.
- This is important where the security of setuid programs is involved.
- .SH "SEE ALSO"
- pipe(2),
- popen(3),
- fopen(3S),
- fclose(3S),
- system(3),
- wait(2),
- sh(1)
- .SH DIAGNOSTICS
- .I Nshpopen
- returns a null pointer if files or processes cannot be created,
- or the shell cannot be accessed.
- .PP
- .I Nshpclose
- returns \-1 if
- .I stream
- is not associated with an `nshpopened' command.
- .SH BUGS
- Buffered reading before opening an input filter
- may leave the standard input of that filter mispositioned.
- Similar problems with an output filter may be
- forestalled by careful buffer flushing, for instance, with
- .I fflush,
- see
- .IR fclose (3).
- .LP
- .I Nshpopen
- does not call a shell to do it's work.
- It does not attempt to process shell meta characters.
- Thus, it does not treat quotes, I/O redirects, or file
- name wildcard characters specially.
- This is it's incompatibility with
- .I popen(3).
- .LP
- This type of function should have been included with
- .I popen(3)
- in the standard I/O library.
- SHAR_EOF
- if test 2367 -ne "`wc -c nshpopen.3l`"
- then
- echo shar: error transmitting nshpopen.3l '(should have been 2367 characters)'
- fi
- cat << \SHAR_EOF > srtunq.3l
- .TH SRTUNQ 1L PUCC
- .SH NAME
- srtinit, srtin, srtgti, srtgets, srtfree, srtdtree
- .SH SYNOPSIS
- .B #include <stdio.h>
- .br
- .B #include <local/srtunq.h>
- .sp
- cc file.c
- .B \-lsrtunq
- .SH DESCRIPTION
- .I Libsrtunq.a
- is a set of sorting routines for a particular purpose.
- It's use is extracting unique items from a possibly long list,
- where items are likely to be replicated numerously.
- The list of unique items will be small enough to
- fit in main memory.
- High speed is desired.
- .PP
- The caller has control over the database through the use of a
- .I struct srtent
- variable.
- The subroutines provide for data entry and retrieval,
- memory allocation and deallocation.
- .SH ROUTINES
- .TP
- .ft B
- void srtinit(ent) struct srtent *ent;
- .ft
- This subroutine must be called before the first time
- any data is entered or retrieved
- from a database tree whose tag is pointed to by
- .B ent.
- It assumes that the database tag has not been used
- to store a tree, and therefore does not attempt to free
- any such data.
- .TP
- .ft B
- char *srtin(ent, string, compar) struct srtent *ent; char *string; int (*compar)();
- .ft
- The existing data tree is searched.
- If the string is found in the tree then nothing is done.
- Otherwise, space is allocated for the string and pointer structure via
- .I malloc(3).
- The string is copied to this new space.
- The structure is linked into the tree.
- If space cannot be obtained, the operation is aborted, and
- a pointer to an error string is returned.
- The data structure remains consistent, but the string is not placed in it.
- If the operation is successful, NULL is returned.
- The strings are compared and sorted with the subroutine pointed to by
- .I compar.
- This subroutine takes two string pointers as arguments.
- It returns zero if the strings are the same,
- less than zero if the first string should precede the second, and
- greater than zero if the second string should precede the first.
- If the subroutine pointer is NULL, then a simple string compare is used, which
- sorts in ascending ASCII order, and strings of different length comparing
- as unequal.
- .TP
- .ft B
- void srtgti(ent); struct srtent *ent;
- .ft
- This subroutine initializes the database tag pointed to by
- .B ent
- so that a tree transversal can be made via
- .I srtgets.
- .TP
- .ft B
- char *srtgets(ent); struct srtent *ent;
- .ft
- This routine extracts the next string from the data structure.
- The strings are returned in increasing order.
- When the list is exhausted, NULL is returned.
- .TP
- .ft B
- void srtfree(ent) struct srtent *ent;
- .ft
- This subroutine deletes a database, and re-initializes the
- database tag.
- It assumes that the database tag was initialized at one time via
- .I srtinit
- (other routines will probably also have been called).
- The space formally occupied by string data and pointer structures is
- deallocated via
- .I free(3).
- .TP
- .ft B
- void srtdtree(ent, tbl) struct srtent *ent; struct srtbl *tbl;
- .ft
- This subroutine recursively deletes a database subtree.
- The space formally occupied by the string data and pointer structures is
- deallocated via
- .I free(3).
- This routine is most likely only of use internally.
- .SH EXAMPLE
- .nf
- main()
- {
- char buf[80], *p;
- struct srtent d;
- srtinit(&d);
- while (fgets(buf, stdin, 79) != NULL)
- if ((p = srtin(&d, "foo")) != NULL)
- printf("test: %s\n", p); /* warning message */
- srtgti(&d);
- while ((p = srtgets(&d)) != NULL)
- puts(p);
- srtfree(&d);
- }
- .fi
- .SH DIAGNOSTICS
- There are no messages printed by these routines.
- Catchable errors are returned as strings.
- Compiled in errors such as the use of strings that
- are not null terminated tend to result in core files.
- .SH FILES
- /usr/local/lib/libsrtunq.a
- .br
- /usr/include/local/srtunq.h
- .SH SEE ALSO
- malloc(3), qsort(3)
- .SH AUTHOR
- Stephen Uitti, PUCC
- .SH BUGS
- Likely.
- SHAR_EOF
- if test 3745 -ne "`wc -c srtunq.3l`"
- then
- echo shar: error transmitting srtunq.3l '(should have been 3745 characters)'
- fi
- chdir ..
- cat << \SHAR_EOF > abrv.c
- /* abbreviation related routines
- * Written & hacked by Stephen Uitti, PUCC staff, ach@pucc-j, 1985
- * maketd is copyright (C) Purdue University, 1985
- *
- * Permission is hereby given for its free reproduction and
- * modification for non-commercial purposes, provided that this
- * notice and all embedded copyright notices be retained.
- * Commercial organisations may give away copies as part of their
- * systems provided that they do so without charge, and that they
- * acknowledge the source of the software.
- */
-
- #ifdef BSD2_9
- #include <sys/types.h>
- #endif
- #include <stdio.h>
- #include <ctype.h>
- extern char *malloc();
-
- #include "srtunq.h"
- #include "abrv.h"
- #include "maketd.h"
-
- struct srtent abrv; /* include file abrevs */
- char *abrvtbl[MXABR]; /* translation table strings */
- int abrvlen[MXABR]; /* string lengths (for speed) */
-
- /* lngsrt - string length more important than lexicographical compare.
- * return > 0 if b is longer than a.
- * return < 0 if b is shorter than a.
- * if a & b are the same length, return strcmp(a, b), which means
- * that 0 is returned if the strings are THE SAME,
- * if b > a: return > 0
- * if b < a: return < 0
- */
- int
- lngsrt(a, b)
- char *a, *b;
- {
- register i;
-
- if ((i = strlen(b) - strlen(a)) != 0)
- return i;
- else
- return strcmp(a, b);
- }
-
- /* hincl - include header optimizer:
- * Compress multiple leading /'s to just one.
- * Remove leading "./".
- * Doesn't change date, just returns pointer into begining of path.
- */
- char *
- hincl(p)
- register char *p;
- {
- if (*p == '/') /* compress multiple leading /'s */
- while (p[1] == '/') /* to just one */
- p++;
- if (strncmp("./", p, 2) == 0) {
- p += 2; /* leading "./" can confuse make */
- while (*p == '/') /* don't change ".//a.h" to "/a.h" */
- p++;
- }
- return p;
- }
-
- /* srchincl - search line for make defines of A-Z
- * Put entries into abrvtbl.
- */
- void
- srchincl(p)
- register char *p;
- {
- register char *q, *r;
- register i;
-
- if (shortincl && *p != '\0') {
- while (*p == SPC || *p == '\t')
- p++; /* ignore white space */
- q = p; /* what letter */
- if (isupper(*p)) { /* A-Z, for now */
- p++;
- while (*p == SPC || *p == '\t')
- p++; /* ignore white space */
- if (*p++ == '=') {
- while (*p == SPC || *p == '\t')
- p++;
- if ((i = strlen(p)) != 0) {
- if ((r = malloc((unsigned)(i + 1))) == NULL)
- err("Out of memory in define search");
- if (abrvtbl[*q - 'A'])
- fprintf(stderr, "%s: warning - %c redefined in %s\n",
- prgnm, *q, makename);
- abrvtbl[*q - 'A'] = r;
- while (*p != '\0' && *p != '#' && *p != '\n')
- *r++ = *p++;
- *r = '\0'; /* null terminate result */
- } /* if non-null string */
- } /* if = */
- } /* if A-Z */
- } /* if shortinclude & string */
- }
-
- /* abrvsetup - set up abrev table, spit out the abrevs. Use
- * any A-Z definitions found in Makefile, no duplicates. Add
- * /usr/include & /usr/include/sys if "all" dependencies are
- * being generated (including /usr/include based files).
- * Try to use I=/usr/include and S=/usr/include/sys, but don't
- * make a stink about it.
- */
- void
- abrvsetup()
- {
- register i; /* temp */
- register char *p; /* temp */
- register slot; /* slot search point */
- register j; /* temp */
- static abrdone = FALSE; /* do this only once */
- register flushi = FALSE; /* print I=.. */
- register flushs = FALSE; /* print S=.. */
- static char *istring = "I=/usr/include";
- static char *sstring = "S=/usr/include/sys";
-
- if (abrdone)
- return;
- if (shortincl) {
- abrdone = TRUE; /* we've done this */
- /* add /usr/include/sys, /usr/include if not already there */
- if (alldep) {
- if (abrvtbl['S'-'A'] == NULL) {
- flushs = TRUE;
- srchincl(sstring);
- } else if ((p = srtin(&abrv, &sstring[2], lngsrt)) != NULL)
- fprintf(stderr, "%s: %s - %s\n", prgnm, p, &sstring[2]);
- if (abrvtbl['I'-'A'] == NULL) {
- flushi = TRUE;
- srchincl(istring);
- } else if ((p = srtin(&abrv, &istring[2], lngsrt)) != NULL)
- fprintf(stderr, "%s: %s - %s\n", prgnm, p, &istring[2]);
- }
- if (!replace) { /* no new defines with replace */
- srtgti(&abrv); /* init tree traversal */
- slot = 0; /* start at bgn */
- while ((p = srtgets(&abrv)) != NULL) {
- j = strlen(p);
- for (i = 0; i < MXABR; i++) { /* look for this definition */
- if (abrvtbl[i] == NULL)
- continue; /* check non-null entries */
- if (*abrvtbl[i] == '\0')
- continue; /* check non-null entries */
- if (strcmp(p, abrvtbl[i]) == 0)
- break; /* exact match found */
- else if (strlen(abrvtbl[i]) == j + 1 &&
- strncmp(p, abrvtbl[i], j) == 0 &&
- abrvtbl[i][j] == '/')
- break; /* match of "p/" found */
- }
- if (i == MXABR) { /* not found */
- for (i = slot; i < MXABR; i++) /* find free slot */
- if (abrvtbl[i] == NULL)
- break;
- if (i < MXABR) { /* free slot found */
- /* if (!usestdout && !replace) */
- fprintf(makefd, "%c=%s\n", 'A' + i, p);
- abrvtbl[i++] = p;
- slot = i; /* reduce free slot search time */
- }
- } /* if not found */
- } /* while */
- } /* if !replace */
- if (flushi && !usestdout && !replace)
- fprintf(makefd, "%s\n", istring);
- if (flushs && !usestdout && !replace)
- fprintf(makefd, "%s\n", sstring);
- for (i = 0; i < MXABR; i++) { /* set up string lengths */
- if (abrvtbl[i] == NULL) {
- abrvlen[i] = 0;
- } else {
- abrvlen[i] = strlen(abrvtbl[i]);
- if (verbose)
- fprintf(stderr, "%s: %c='%s'\n",
- prgnm, i + 'A', abrvtbl[i]);
- } /* if */
- } /* for */
- } /* if */
- }
-
- /* findabr - find an abbreviation in abrvtbl for string p (if any).
- * if multiple abbreations work, use longest.
- * (ie: /usr/include & /usr/include/sys; use /usr/include/sys)
- * if found, return index
- * else: MXABR
- * Do not match abbreviations of less than 3 characters.
- */
- int
- findabr(p)
- register char *p; /* string pointer */
- {
- register i; /* for index */
- register j; /* found index */
-
- for (i = 0, j = MXABR; i < MXABR; i++)
- if (abrvlen[i] > 2) /* changing "." to $A is evil */
- if (strncmp(abrvtbl[i], p, abrvlen[i]) == 0)
- if (j == MXABR || (abrvlen[i] > abrvlen[j]))
- j = i;
- return j;
- }
- SHAR_EOF
- if test 6197 -ne "`wc -c abrv.c`"
- then
- echo shar: error transmitting abrv.c '(should have been 6197 characters)'
- fi
- cat << \SHAR_EOF > abrv.h
- /* include srtunq.h first */
-
- #define MXABR 26 /* upper case chars used */
- extern char *abrvtbl[]; /* translation table strings */
- extern int abrvlen[]; /* string lengths (for speed) */
- extern SRTUNQ abrv; /* include file abrevs */
-
- /* abbreviation fucntions */
- extern int lngsrt(); /* compare function for abrevs */
- extern char *hincl(); /* optimizer for include paths */
- extern void srchincl(); /* find [A-Z] makefile defines */
- extern void abrvsetup(); /* create abrvs, write them */
- extern int findabr(); /* find longest abrv */
- SHAR_EOF
- if test 544 -ne "`wc -c abrv.h`"
- then
- echo shar: error transmitting abrv.h '(should have been 544 characters)'
- fi
- cat << \SHAR_EOF > breakargs.c
- /* breakargs - break a string into a string vector for execv.
- * Returns NULL if can't malloc space for vector, else vector.
- * Note, when done with the vector, mearly "free" the vector.
- * Written by Stephen Uitti, PUCC, Nov '85 for the new version
- * of "popen" - "nshpopen", that doesn't use a shell.
- * (used here for the as filters, a newer option).
- *
- * breakargs is copyright (C) Purdue University, 1985
- *
- * put in a fix for cmds lines with "string string" in them
- * Mon Aug 25 13:34:27 EST 1986 (ksb)
- *
- * Permission is hereby given for its free reproduction and
- * modification for non-commercial purposes, provided that this
- * notice and all embedded copyright notices be retained.
- * Commercial organisations may give away copies as part of their
- * systems provided that they do so without charge, and that they
- * acknowledge the source of the software.
- */
- #ifdef BSD2_9
- #include <sys/types.h>
- #endif
- #include <stdio.h> /* for nothing, really */
- #define SPC '\040' /* ascii space */
-
- char *
- mynext(pch)
- register char *pch;
- {
- register int fQuote;
-
- for (fQuote = 0; (*pch != '\000' && *pch != SPC && *pch != '\t')||fQuote; ++pch) {
- if ('\\' == *pch) {
- continue;
- }
- switch (fQuote) {
- default:
- case 0:
- if ('"' == *pch) {
- fQuote = 1;
- } else if ('\'' == *pch) {
- fQuote = 2;
- }
- break;
- case 1:
- if ('"' == *pch)
- fQuote = 0;
- break;
- case 2:
- if ('\'' == *pch)
- fQuote = 0;
- break;
- }
- }
- return pch;
- }
-
- char **
- breakargs(cmd)
- char *cmd;
- {
- register char *p; /* tmp */
- register char **v; /* vector of commands returned */
- register unsigned sum; /* bytes for malloc */
- register int i; /* number of args */
- register char *s; /* save old position */
- char *malloc(), *strcpy();
-
- p = cmd;
- while (*p == SPC || *p == '\t')
- p++;
- cmd = p; /* no leading spaces */
- sum = sizeof(char *);
- i = 0;
- while (*p != '\0') { /* space for argv[]; */
- ++i;
- s = p;
- p = mynext(p);
- sum += sizeof(char *) + 1 + (unsigned)(p - s);
- while (*p == SPC || *p == '\t')
- p++;
- }
- ++i;
- /* vector starts at v, copy of string follows NULL pointer */
- v = (char **)malloc(sum+1);
- if (v == NULL)
- return (char **)NULL;
- p = (char *)v + i * sizeof(char *); /* after NULL pointer */
- i = 0; /* word count, vector index */
- while (*cmd != '\0') {
- v[i++] = p;
- s = cmd;
- cmd = mynext(cmd);
- if (*cmd != '\0')
- *cmd++ = '\0';
- strcpy(p, s);
- p += strlen(p);
- ++p;
- while (*cmd == SPC || *cmd == '\t')
- ++cmd;
- }
- v[i] = (char *)NULL;
- return v;
- }
- SHAR_EOF
- if test 2529 -ne "`wc -c breakargs.c`"
- then
- echo shar: error transmitting breakargs.c '(should have been 2529 characters)'
- fi
- cat << \SHAR_EOF > maketd.c
- /* maketd - MAKE Transitive Dependencies.
- * (This is a lie - the dependencies are not transitive, but "all"
- * dependencies are correctly made.)
- *
- * Based loosely on a shell script by Stephan Bechtolsheim, svb@purdue
- * Other Makefile related features have been added or merged in from
- * other programs.
- *
- * Written & hacked by Stephen Uitti, PUCC staff, ach@pucc-j, 1985
- * maketd is copyright (C) Purdue University, 1985
- *
- * removed some of Steve's good, but unnecessary, options in favor
- * of more compile time flags & better implicit rules in the makefile
- * dinked: -q -e -E -k
- * Kevin S Braunsdorf, PUCC UNIX Group 1986 (ksb@j.cc.purdue.edu)
- *
- * Permission is hereby given for its free reproduction and
- * modification for non-commercial purposes, provided that this
- * notice and all embedded copyright notices be retained.
- * Commercial organisations may give away copies as part of their
- * systems provided that they do so without charge, and that they
- * acknowledge the source of the software.
- */
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/file.h> /* for access */
- #ifdef BSD2_9
- #include <ndir.h> /* for MAXPATHLEN, MAXNAMLEN */
- #endif
- #ifdef BSD4_2
- #include <sys/dir.h> /* for MAXNAMLEN in 4.2 */
- #endif
- #include <ctype.h> /* for isupper */
- #include <stdio.h>
- extern char *rindex(), *index(), *strcat(), *strcpy();
-
- #include "srtunq.h"
- #include "abrv.h"
- #include "nshpopen.h"
- #include "maketd.h"
-
- #ifndef CPP
- #define CPP "/lib/cpp "
- #endif CPP not in Makefile
-
- /* forward functions */
- void msoio(); /* open output file */
- void rdwr(); /* read old Makefile into new */
- void mkdepend(); /* does the real work */
-
- /* globals */
- char *prgnm; /* our program name */
- FILE *makefd; /* makefile stream */
- int alldep = FALSE; /* -a all - /usr/include too */
- char *targetname = NULL; /* -t target name for next file */
- char *destsuffix = ".o"; /* -s suffix for targets */
- int header = TRUE; /* print header & trailer */
- int usestdout = FALSE; /* -d use stdout for makefile */
- int forcehead = FALSE; /* -f force header/trailer */
- int makenseen = FALSE; /* output file has been specified */
- char *makename = "makefile"; /* -m default file for edit */
- int backedup = FALSE; /* for interupt recovery */
- char backupfn[MAXNAMLEN+1]; /* backup file name */
- int ismakeopen = FALSE; /* if the output file is open */
- char objpath[MAXPATHLEN+1]; /* -o prepended to .o's */
- int nonlocalo = FALSE; /* -nonlocalo objects in source dir */
- int replace = FALSE; /* -r replace depends in Makefile */
- char cppflags[BUFSIZ]; /* -D, -I, -U flags to pass to cpp */
- int shortincl = TRUE; /* -x do abreviations */
- int verbose = FALSE; /* -v verbage for the debugger */
- static char sopts[] = "abdfhrxv"; /* single char opts */
- static SRTUNQ u; /* unique include files */
-
- char usage[] =
- "Usage: maketd [-a -b -d -f -h -mMAKEFILE -nonlocalo -oDIR -r -sSUFFIX\n\
- -tTARGETNAME -x -v -Iincludedir -Ddefine -Uundefine file...]\n";
- char helptext[] =
- "-a\tdo all dependencies, including /usr/include\n\
- -b\tgenerate binary, rather than object related dependencies\n\
- -d\tdependencies to stdout, rather than Makefile\n\
- -f\tforce header/trailer (use with -d)\n\
- -h\thelp (this text)\n\
- -m\tspecify MAKEFILE for edit\n\
- -nonlocalo Objects live in source directory\n\
- -o\tprepend DIR to target: DIR/a.o: foo.h\n\
- -r\treplace dependencies for a target\n\
- -s\tchange suffix target's SUFFIX: a.SUFFIX: foo.h\n\
- -t\tchange target's basename: TARGET.o: foo.h\n\
- -x\tdon't abbreviate includes\n\
- -v\tprint extra verbose (debug) output to stderr\n\
- -I\tspecify include directory, as in /lib/cpp\n\
- -D\tspecify defines, as in /lib/cpp\n\
- -U\tspecify undefines, as in /lib/cpp\n";
-
- char deplin[] = "# DO NOT DELETE THIS LINE - make depend DEPENDS ON IT\n";
- char searchdep[] = "# DO NOT DELETE THIS LINE";
- char trailer[] = "\n# *** Do not add anything here - It will go away. ***\n";
-
- /* some init & argv parsing */
- main(argc, argv)
- register int argc;
- register char **argv;
- {
- register a; /* argv subscript */
- register i; /* tmp */
- register len; /* length of current argument */
- register files = FALSE; /* files ever seen */
- register char *q; /* tmp */
-
- /* prgnm = program name, for error printing */
- if ((prgnm = rindex(argv[0], '/')) == NULL)
- prgnm = argv[0];
- else
- prgnm++;
- catchsig(); /* init signal traps */
- srtinit(&abrv); /* init abbreviations tree */
- for (a = 1; a < argc; a++) { /* argv prepass: find all -I's */
- if (argv[a][0] == '-' && argv[a][1] == 'I' && strlen(&argv[a][2]) > 2)
- if ((q = srtin(&abrv, hincl(&argv[a][2]), lngsrt)) != NULL)
- fprintf(stderr, "%s: %s - %s\n", prgnm, q, &argv[a][2]);
- }
- cppflags[0] = '\0'; /* terminate cpp flags string */
- objpath[0] = '\0'; /* init object path */
- srtinit(&u); /* init sorting database tag */
- for (a = 1; a < argc; a++) {
- len = strlen(argv[a]);
- if (argv[a][0] == '-' && len > 2 && index(sopts, argv[a][1]) != NULL)
- err("options must be listed seperately - '%s'\n", argv[a]);
- if (len > 1 && argv[a][0] == '-') {
- switch (argv[a][1]) {
- case 'D': /* /lib/cpp flags to pass */
- case 'I':
- case 'U':
- if (strlen(cppflags) + strlen(argv[a]) + 2 > BUFSIZ)
- err("too many cpp flags - buffer overflow");
- strcat(cppflags, argv[a]);
- strcat(cppflags, " "); /* add a space separator */
- break;
- case 'a': /* /usr/include deps too */
- alldep = TRUE;
- break;
- case 'b': /* target has no suffix */
- destsuffix = "";
- break;
- case 'd': /* don't edit Makefile */
- if (ismakeopen)
- err("Makefile already open, -d must precede filenames");
- if (makenseen)
- err("Conflict - check -d and -m options");
- makenseen = TRUE;
- usestdout = TRUE;
- if (!forcehead)
- header = FALSE; /* don't do header & trailer */
- break;
- case 'f': /* force header/trailer */
- forcehead = TRUE;
- header = TRUE;
- break;
- case 'h': /* help */
- fputs(usage, stdout);
- fputs(helptext, stdout);
- exit(0);
- break;
- case 'm': /* specify makefile name for edit */
- if (ismakeopen)
- err("Makefile already open, -m must precede filenames");
- if (makenseen)
- err("Conflict, check -m and -d options.");
- if (strlen(makename) == 0)
- err("-m option requires file name.");
- makenseen = TRUE;
- makename = &argv[a][2];
- break;
- case 'n': /* objects reside with sources */
- if (strcmp("nonlocalo", &argv[a][1]) != 0)
- err("bad -n option"); /* what a crock of an option */
- if (objpath[0] != '\0')
- err("nonlocalo conflict - check -o's");
- nonlocalo = TRUE;
- break;
- case 'o':
- if (nonlocalo)
- err("object path conflict - check -o's and -nonlocalo's");
- strcpy(objpath, &argv[a][2]);
- i = strlen(objpath);
- if (i == 0)
- err("-o requires path string.");
- if (i >= MAXPATHLEN)
- err("Object path too long: max is %d.", MAXPATHLEN);
- if (objpath[i - 1] != '/')
- strcat(objpath, "/");
- break;
- case 'r': /* replace mode */
- if (ismakeopen)
- err("Makefile already open, -r must precede filenames");
- replace = TRUE;
- break;
- case 's': /* destination suffix */
- destsuffix = &argv[a][2];
- break;
- case 't': /* set target's basename */
- targetname = &argv[a][2];
- if (len <= 2)
- err("target option requires name.");
- break;
- case 'v': /* user wants to hear noise */
- verbose = TRUE;
- break;
- case 'x': /* don't abbrev. */
- if (files)
- err("-x option must preceed all files.");
- shortincl = FALSE;
- break;
- default:
- err("Unknown option %s.", argv[a]);
- } /* end switch */
- } else { /* must be a filename */
- if (verbose)
- fprintf(stderr, "%s: working on %s.\n", prgnm, argv[a]);
- files = TRUE; /* at least one file seen */
- if (replace && a != argc - 1)
- err("Only one file allowed with -r (edit aborted)");
- mkdepend(argv[a]); /* file to process */
- targetname = NULL; /* affect only one file */
- } /* if option */
- } /* for argv */
- if (ismakeopen && header)
- fputs(trailer, makefd); /* do not delete... */
- #if DEL_BACKUP
- if (backedup)
- if (unlink(backupfn))
- err("Can't delete backup file %s on completion", backupfn);
- #endif DEL_BACKUP
- if (!files)
- err("No files to process, use -h for full help.\n%s", usage);
- exit(0); /* exit status - good */
- }
-
- /* msoio - Make Sure Output Is Open.
- * Interacts strongly via globals: makefd, backedup, backupfn, makename,
- * header, ismakeopen
- */
- void
- msoio(targ)
- char *targ; /* if -r, is target name */
- {
- FILE *tmpfd; /* temp file desc for -d */
- char buf[BUFSIZ]; /* for reading the makefile */
-
- if (ismakeopen)
- return;
- ismakeopen = TRUE; /* will be: all errs are fatal */
- if (usestdout) {
- makefd = stdout;
- if (header) {
- fputc('\n', makefd); /* one blank line */
- fputs(deplin, makefd); /* the first line */
- }
- /* scan "makefile" or "Makefile" for include defines */
- if (access(makename, R_OK) != 0) {
- makename[0] = 'M'; /* try Makefile */
- if (access(makename, R_OK) != 0)
- return; /* just punt */
- }
- if ((tmpfd = fopen(makename, "r")) == NULL)
- return; /* just punt */
- while (fgets(buf, BUFSIZ, tmpfd) != NULL)
- srchincl(buf); /* scan whole file */
- fclose(tmpfd);
- return;
- } /* ... if standard out */
- /* !makenseen means (default) try "makefile" then "Makefile" */
- if (!makenseen && access(makename, F_OK) != 0)
- makename[0] = 'M'; /* try Makefile */
- /* side effect: "Makefile" will be created if neither exist */
- if (access(makename, F_OK) == 0) { /* if makefile exits */
- strcpy(backupfn, makename); /* get rid of .bak */
- strcat(backupfn, ".bak");
- if (access(backupfn, F_OK) == 0) {
- if (unlink(backupfn))
- err("Can't remove %s for pre-edit\n", backupfn);
- }
- if (link(makename, backupfn)) /* mv makefile to .bak */
- err("Can't link %s to %s.", backupfn, makename);
- backedup = TRUE; /* for interupt status */
- if (unlink(makename))
- err("Can't unlink %s during rename.", makename);
- } else {
- backupfn[0] = '\0'; /* no copy (no makefile) */
- }
- if ((makefd = fopen(makename, "w")) == NULL)
- err("Can't open output file '%s' for write.", makename);
- if (backupfn[0] != '\0') /* if no .bak file - done */
- rdwr(targ); /* read/write Makefile */
- else
- fputs(deplin, makefd); /* must start with this */
- }
-
- /* create beginging of new Makefile by reading old one */
- void
- rdwr(targ)
- char *targ;
- {
- register FILE *oldfd; /* file pointer for .old */
- char rwbuf[BUFSIZ]; /* temp for read/write */
- register tlen; /* targ length */
- register puntln = FALSE; /* punt current line? */
- register contln = FALSE; /* previous line ended with '\'? */
- register blankln = 0; /* number of blank lines seen */
- register srchsn = FALSE; /* search line seen? */
-
- if ((oldfd = fopen(backupfn, "r")) == NULL)
- err("Can't open backup copy of %s\n", makename);
- tlen = strlen(targ);
- while (fgets(rwbuf, BUFSIZ, oldfd) != NULL) { /* until EOF */
- if (!srchsn) {
- if (strncmp(searchdep, rwbuf, (sizeof searchdep) - 1) == 0) {
- srchsn = TRUE;
- fputs(deplin, makefd); /* re-write this line */
- if (!replace)
- break;
- continue; /* don't print this line */
- }
- } else {
- if (strcmp("\n", rwbuf) == 0) {
- if (!puntln)
- blankln++;
- contln = FALSE;
- puntln = FALSE;
- continue; /* don't output this blank line */
- }
- if (!contln) {
- if (strncmp(targ, rwbuf, tlen) == 0)
- puntln = TRUE;
- else if (strcmp(&trailer[1], rwbuf) == 0)
- puntln = TRUE;
- }
- if (lastlnch(rwbuf) == '\\')
- contln = TRUE;
- else
- contln = FALSE;
- } /* if srchsn */
- if (!puntln) {
- srchincl(&rwbuf[0]); /* search this line for defines */
- if (blankln != 0) { /* compress mult blank lines to one */
- putc('\n', makefd);
- blankln = 0;
- }
- fputs(rwbuf, makefd); /* non targ lines */
- }
- } /* while fgets */
- if (!srchsn) /* deplin never found */
- fputs(deplin, makefd); /* so write one */
- (void) fclose(oldfd); /* close the .old file for gigles */
- }
-
- #define MAXCOL 78 /* output width max for makefile */
-
- /* mkdepend - name is historical, but does the "real work" */
- void
- mkdepend(infile)
- char *infile;
- {
- register char *p; /* temp pointer */
- register char *q; /* temp pointer */
- register char *r; /* temp pointer */
- register FILE *cppfd; /* file desc for /lib/cpp */
- char buf[BUFSIZ]; /* temp buff */
- char basename[MAXNAMLEN+1]; /* just the file name */
- register oplen; /* length target & path */
- register le; /* length of current output line */
- register char *targ; /* target's name */
- register i; /* tmp for index */
- register firstln; /* first line of a list */
-
- if ((p = rindex(infile, '/')) == NULL) /* past path */
- p = infile;
- else
- p++;
- if (nonlocalo && p != infile) { /* objpath = source path */
- for (q = objpath, r = infile; r < p;)
- *q++ = *r++;
- *q = '\0'; /* null terminate */
- }
- strcpy(basename, p);
- if ((p = rindex(basename, '.')) != NULL)
- *p = '\0'; /* remove trailing ".*" */
- if (targetname != NULL) /* set up target's name */
- targ = targetname;
- else
- targ = basename;
- if (makename == NULL) {
- makename = "Makefile";
- if (access(makename, F_OK) != 0)
- makename[0] = 'm'; /* not a real check */
- }
- msoio(targ); /* Make Sure Output Is Open */
- abrvsetup(); /* create abrev table, write defs. */
- if (access(infile, R_OK) != 0) {
- fprintf(stderr, "%s: Can't open input file '%s', skipped.\n",
- prgnm, infile);
- return;
- }
- (void)strcpy(buf, CPP); /* build cpp cmd line */
- #if CPP_M
- strcat(buf, "-M "); /* -M flag - does dependencies */
- #endif
- if (strlen(buf) + strlen(cppflags) + strlen(infile) + 1 > BUFSIZ)
- err("cpp command line buffer overflow");
- (void)strcat(buf, cppflags); /* add command flags */
- (void)strcat(buf, infile); /* add file name */
- srtfree(&u); /* init insertion sorter */
- if (verbose)
- fprintf(stderr, "%s: cpp line is '%s'\n", prgnm, buf);
- if ((cppfd = nshpopen(buf, "r")) == NULL)
- err("Can't open pipe for %s", buf);
- #if CPP_M
- while (fgets(buf, BUFSIZ, cppfd) != NULL) {
- if ((p = index(buf, ':')) == NULL)
- err("cpp -M format error - colon");
- p++; /* pass colon */
- if (*p++ != SPC)
- err("cpp -M format error - space");
- p = hincl(p); /* skip any uglies in include path */
- if (!alldep && strncmp("/usr/include", p, 12) == 0)
- continue; /* ignore /usr/include... stuff */
- if (index(p, '\n') != NULL) /* replace newline with EOS */
- *index(p, '\n') = '\0';
- if ((q = srtin(&u, p, (int (*)())0)) != NULL) /* insert into list */
- fprintf(stderr, "%s: %s - %s\n", prgnm, q, p); /* warning */
- }
- #else
- while (fgets(buf, BUFSIZ, cppfd) != NULL) {
- if (buf[0] != '#') /* must start with '#' */
- continue;
- if ((p = index(buf, '"')) == NULL) /* find first double quote */
- continue;
- p++;
- p = hincl(p); /* skip any uglies in include path */
- if (index(p, '"') != NULL) /* terminate the file name */
- *index(p, '"') = '\0';
- if (!alldep && strncmp("/usr/include", p, 12) == 0)
- continue; /* ignore /usr/include... stuff */
- if ((q = srtin(&u, p, (int (*)())0)) != NULL) /* insert into list */
- fprintf(stderr, "%s: %s - %s\n", prgnm, q, p); /* warning */
- }
- #endif
- srtgti(&u); /* init for srtgets */
- /* 2 for colon space */
- oplen = strlen(objpath) + strlen(targ) + strlen(destsuffix) + 2;
- le = MAXCOL; /* force new line output */
- firstln = TRUE; /* first line of a file entry */
- while ((p = srtgets(&u)) != NULL) { /* write out the entries */
- if (shortincl)
- if ((i = findabr(p)) != MXABR) /* i = found index or MXABR */
- p += abrvlen[i] - 2;
- if (le + strlen(p) >= MAXCOL) {
- if (firstln) {
- le = oplen;
- fprintf(makefd, "\n%s%s%s: ", objpath, targ, destsuffix);
- firstln = FALSE;
- } else {
- le = 8;
- fprintf(makefd, " \\\n\t");
- }
- } else {
- fputc(SPC, makefd);
- }
- if (shortincl && i != MXABR) {
- fprintf(makefd, "$%c", 'A' + i);
- p += 2; /* right place */
- le += 2;
- }
- fputs(p, makefd);
- le += 1 + strlen(p);
- }
- fputc('\n', makefd); /* end with newline */
- nshpclose(cppfd); /* end of that file */
- }
- SHAR_EOF
- if test 16381 -ne "`wc -c maketd.c`"
- then
- echo shar: error transmitting maketd.c '(should have been 16381 characters)'
- fi
- cat << \SHAR_EOF > maketd.h
- #define TRUE 1
- #define FALSE 0
- #define SPC '\040'
-
- /* globals */
- extern char *prgnm; /* the progs called name */
- extern int alldep; /* -a all - /usr/include too */
- extern int usestdout; /* -d use stdout for makefile */
- extern FILE *makefd; /* file desc. for output file */
- extern char *makename; /* -m default file for edit */
- extern int backedup; /* for interupt recovery */
- extern char backupfn[]; /* backup file name */
- extern int replace; /* -r replace depends in Makefile */
- extern int shortincl; /* -x do abreviations */
- extern int verbose; /* -v verbage for the debugger */
- extern char usage[]; /* for error output */
-
- extern void err(); /* error msg, exit cleanly */
- extern void errrec(); /* exit cleanly - also signal trap */
- extern char lastlnch(); /* last char in line (not \n) */
- SHAR_EOF
- if test 809 -ne "`wc -c maketd.h`"
- then
- echo shar: error transmitting maketd.h '(should have been 809 characters)'
- fi
- cat << \SHAR_EOF > misc.c
- /* Written & hacked by Stephen Uitti, PUCC staff, ach@pucc-j, 1985
- * maketd is copyright (C) Purdue University, 1985
- *
- * Permission is hereby given for its free reproduction and
- * modification for non-commercial purposes, provided that this
- * notice and all embedded copyright notices be retained.
- * Commercial organisations may give away copies as part of their
- * systems provided that they do so without charge, and that they
- * acknowledge the source of the software.
- */
-
- #ifdef BSD2_9
- #include <sys/types.h>
- #include <signal.h>
- #endif
- #ifdef BSD4_2
- #include <sys/signal.h>
- #endif
- #include <stdio.h>
-
- #include "maketd.h"
-
- /* VARARGS */
- /* print and error and exit */
- void
- err(a, b, c, d)
- char *a; /* the format string, as printf */
- char *b, *c, *d; /* arguments, as printf */
- {
- fprintf(stderr, "%s: ", prgnm);
- fprintf(stderr, a, b, c, d);
- fprintf(stderr, "\n");
- errrec(); /* clean up backup file, if any */
- exit(1);
- }
-
- /* errrec - error recovery: recover temp file */
- static void
- errrec()
- {
- if (backedup) {
- backedup = FALSE; /* prevent infinite error recursion */
- unlink(makename); /* may or may not exist */
- if (link(backupfn, makename))
- err("can't link %s to %s during recovery", makename, backupfn);
- if (unlink(backupfn))
- err("can't delete %s during recovery", backupfn);
- err("edit of '%s' aborted - file unchanged.", makename);
- }
- exit(1);
- }
-
- /* signal trap routines, one for each */
- static void
- errhup()
- {
- fprintf(stderr, "%s: SIGHUP recieved\n", prgnm);
- errrec();
- }
-
- static void
- errint()
- {
- fprintf(stderr, "%s: SIGINT recieved\n", prgnm);
- errrec();
- }
-
- static void
- errill()
- {
- fprintf(stderr, "%s: SIGILL recieved\n", prgnm);
- errrec();
- }
-
- static void
- errtrap()
- {
- fprintf(stderr, "%s: SIGTRAP recieved\n", prgnm);
- errrec();
- }
-
- static void
- erriot()
- {
- fprintf(stderr, "%s: SIGIOT recieved\n", prgnm);
- errrec();
- }
-
- static void
- erremt()
- {
- fprintf(stderr, "%s: SIGEMT recieved\n", prgnm);
- errrec();
- }
-
- static void
- errfpe()
- {
- fprintf(stderr, "%s: SIGFPE recieved\n", prgnm);
- errrec();
- }
-
- static void
- errbus()
- {
- fprintf(stderr, "%s: SIGBUS recieved\n", prgnm);
- errrec();
- }
-
- static void
- errsegv()
- {
- fprintf(stderr, "%s: SIGSEGV recieved\n", prgnm);
- errrec();
- }
-
- static void
- errsys()
- {
- fprintf(stderr, "%s: SIGSYS recieved\n", prgnm);
- errrec();
- }
-
- static void
- errpipe()
- {
- fprintf(stderr, "%s: SIGPIPE recieved\n", prgnm);
- errrec();
- }
-
- static void
- erralrm()
- {
- fprintf(stderr, "%s: SIGALRM recieved\n", prgnm);
- errrec();
- }
-
- static void
- errterm()
- {
- fprintf(stderr, "%s: SIGTERM recieved\n", prgnm);
- errrec();
- }
-
- /* catchsig - init signal traps */
- catchsig()
- {
- signal(SIGHUP, errhup);
- signal(SIGINT, errint);
- signal(SIGILL, errill);
- signal(SIGTRAP, errtrap);
- signal(SIGIOT, erriot);
- signal(SIGEMT, erremt);
- signal(SIGFPE, errfpe);
- signal(SIGBUS, errbus);
- signal(SIGSEGV, errsegv);
- signal(SIGSYS, errsys);
- signal(SIGPIPE, errpipe);
- signal(SIGALRM, erralrm);
- signal(SIGTERM, errterm);
- /* Stock 2.9BSD has all the above, but not as many as 4.2BSD:
- * Want SIGQUIT to drop core.
- * Not worrying about: SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF
- * cannot be caught: SIGKILL, SIGSTOP
- * Leaving alone: SIGURG, SIGTSTP, SIGCONT, SIGCHLD, SIGTTIN, SIGTTOU, SIGIO
- */
- }
-
- /* lastlnch - return last char before newline or NULL in string */
- char
- lastlnch(p)
- register char *p;
- {
- register char *q;
-
- q = p;
- while (*p != '\0' && *p != '\n')
- q = p++;
- return *q;
- }
- SHAR_EOF
- if test 3572 -ne "`wc -c misc.c`"
- then
- echo shar: error transmitting misc.c '(should have been 3572 characters)'
- fi
- cat << \SHAR_EOF > nshpopen.c
- /* @(#)popen.c 4.5 (Berkeley) 7/6/84
- * Modified from 4.2, 2.9 BSD popen by Stephen Uitti, PUCC, Nov '85
- * Doesn't invoke shell, saving time, becoming more secure.
- * Calls breakargs to break line into command line arguments,
- * delimited by white space, but ignores globing and quoting
- * characters. For use where you don't need shell meta character
- * expansion or filename globbing.
- */
- #ifdef BSD2_9
- #include <sys/types.h>
- #endif
- #include <stdio.h>
- #include <signal.h>
-
- #define tst(a,b) (*mode == 'r'? (b) : (a))
- #define RDR 0
- #define WTR 1
- #define SPC '\040' /* ascii space */
-
- static int popen_pid[20];
- extern char **environ;
- char **breakargs();
-
- /* no-shell popen */
- FILE *
- nshpopen(cmd, mode)
- char *cmd;
- char *mode;
- {
- int p[2];
- int myside, hisside, pid;
- char **elist; /* the execv list */
-
- elist = breakargs(cmd);
- if (pipe(p) < 0)
- return (NULL);
- myside = tst(p[WTR], p[RDR]);
- hisside = tst(p[RDR], p[WTR]);
- if ((pid = vfork()) == 0) {
- /* myside and hisside reverse roles in child */
- close(myside);
- if (hisside != tst(0, 1)) { /* 0, 1 => stdin, stdout */
- dup2(hisside, tst(0, 1));
- close(hisside);
- }
- execve(elist[0], elist, environ);
- perror("execv");
- _exit(1); /* bombed execv, child dies */
- }
- free(elist); /* discard the broken args */
- if (pid == -1) {
- close(myside);
- close(hisside);
- return (NULL);
- }
- popen_pid[myside] = pid;
- close(hisside);
- return (fdopen(myside, mode));
- }
-
- /* close for nshpopen */
- int *
- nshpclose(ptr)
- FILE *ptr;
- {
- #ifdef BSD4_2
- int child, pid, status, omask;
-
- child = popen_pid[fileno(ptr)];
- fclose(ptr);
- #define mask(s) (1 << ((s)-1))
- omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGHUP));
- while ((pid = wait(&status)) != child && pid != -1)
- /* empty */;
- (void) sigsetmask(omask);
- return (int *)(pid == -1 ? -1 : status);
- #else /* 2.9 BSD, at least */
- register f, r, (*hstat)(), (*istat)(), (*qstat)();
- int status;
-
- f = fileno(ptr);
- fclose(ptr);
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
- hstat = signal(SIGHUP, SIG_IGN);
- while((r = wait(&status)) != popen_pid[f] && r != -1)
- ;
- if(r == -1)
- status = -1;
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
- signal(SIGHUP, hstat);
- return (int *)(status);
- #endif BSD4_2
- }
- SHAR_EOF
- if test 2253 -ne "`wc -c nshpopen.c`"
- then
- echo shar: error transmitting nshpopen.c '(should have been 2253 characters)'
- fi
- cat << \SHAR_EOF > nshpopen.h
- /* nshpopen defines */
- extern FILE *nshpopen(); /* open pipe */
- extern int *nshpclose(); /* close pipe */
- SHAR_EOF
- if test 113 -ne "`wc -c nshpopen.h`"
- then
- echo shar: error transmitting nshpopen.h '(should have been 113 characters)'
- fi
- cat << \SHAR_EOF > srtunq.c
- /* Sorting function that inserts strings one at a time into memory.
- * Strings are null terminated.
- * Only uniq strings are stored (no count is kept of how many)
- * Any memory used is freed on init (or re-init).
- *
- * Author: Stephen Uitti, PUCC, 1985
- * libsrtunq is copyright (C) Purdue University, 1985
- *
- * Permission is hereby given for its free reproduction and
- * modification for non-commercial purposes, provided that this
- * notice and all embedded copyright notices be retained.
- * Commercial organisations may give away copies as part of their
- * systems provided that they do so without charge, and that they
- * acknowledge the source of the software.
- */
-
- #ifndef lint
- static char *rcsid =
- "$Id: srtunq.c,v 1.4 86/08/30 21:35:36 ksb Exp Locker: ksb $";
- #endif
-
- #ifdef BSD2_9
- #include <sys/types.h>
- #endif
- #ifdef notdef /* a comment that allows comments. */
- * use:
- * #include <local/srtunq.h> /* defines, etc */
- * struct srtent d; /* data structure foothold */
- * char *p; /* temp */
- * srtinit(&d); /* init the structure */
- * if ((p = srtin(&d, "foo", NULL)) != NULL) err(p); /* add the data */
- * ...
- * srtgti(&d); /* init for get */
- * p = srtgets(&d); /* get next entry */
- * ...
- * srtfree(&d); /* delete the structure */
- #endif
-
- #include <stdio.h> /* for null */
- #include <sys/types.h> /* for void, in V7 */
- #include "srtunq.h" /* for srtunq structs & functions */
- /* #include <local/srtunq.h> /* for srtunq structs & functions */
-
- /* libc functions */
- char *malloc(); /* need more memory */
- char *strcpy(); /* copy string */
-
- /* srtgti - init get string function */
- void
- srtgti(ent)
- struct srtent *ent;
- {
- ent->srt_next = ent->srt_top;
- if (ent->srt_next == NULL)
- return;
- while (ent->srt_next->srt_less != NULL)
- ent->srt_next = ent->srt_next->srt_less;
- }
-
- /* srtgets - get next string from sorted list, NULL if none more. */
- /* The least shall be first... and the greatest shall be last */
- char *
- srtgets(ent)
- struct srtent *ent;
- {
- register struct srtbl *s; /* tmp */
- register char *p; /* ret val */
-
- if ((s = ent->srt_next) == NULL)
- return NULL;
- p = s->srt_str; /* ret val */
- if (s->srt_more != NULL) {
- s = s->srt_more; /* go one more */
- while (s->srt_less != NULL) /* then all the way less */
- s = s->srt_less;
- ent->srt_next = s;
- return p;
- }
- while (s != ent->srt_top && s->srt_prev->srt_more == s)
- s = s->srt_prev; /* back down any more's */
- if (s == ent->srt_top)
- s = NULL; /* no more */
- else
- s = s->srt_prev;
- ent->srt_next = s;
- return p;
- }
-
- /* srtinit - init the database tag */
- void
- srtinit(ent)
- struct srtent *ent;
- {
- ent->srt_top = NULL; /* erase any knowledge of it */
- ent->srt_next = NULL; /* extractions at the begining */
- }
-
- /* srtfree - delete all the data, init the tag */
- void
- srtfree(ent)
- struct srtent *ent;
- {
- if (ent->srt_top == NULL) /* is the structure empty? */
- return; /* yes - exit */
- srtdtree(ent->srt_top);
- free((char *)ent->srt_top); /* clean up last struct */
- srtinit(ent); /* init the tag */
- }
-
- /* srtdtree - recursive tree delete
- * frees all less & more entries pointed to by the srt struct */
- void
- srtdtree(srt)
- register struct srtbl *srt;
- {
- if (srt->srt_less != NULL) {
- srtdtree(srt->srt_less);
- free((char *)srt->srt_less);
- srt->srt_less = NULL; /* for consistency */
- }
- if (srt->srt_more != NULL) {
- srtdtree(srt->srt_more);
- free((char *)srt->srt_more);
- srt->srt_more = NULL;
- }
- }
-
- /* srtin - insert string sorted & unique.
- * returns NULL if good, else error message string. */
- char *
- srtin(ent, str, compar)
- struct srtent *ent;
- char *str;
- int (*compar)(); /* if NULL: use strcmp */
- {
- register char *p; /* temp string pointer */
- register i; /* string compare result */
- register struct srtbl *s; /* temp */
- register struct srtbl *srtold; /* old temp */
-
- s = srtold = ent->srt_top;
- while (s != NULL) {
- if ((i = (compar == NULL ?
- strcmp(str, s->srt_str) : (*compar)(str, s->srt_str))) == 0)
- return NULL; /* found: do nothing - "good" */
- srtold = s;
- if (i > 0)
- s = s->srt_more;
- else
- s = s->srt_less;
- }
- if ((p = malloc((unsigned)(strlen(str) + sizeof(struct srtbl)))) == NULL)
- return "srtin: warning - out of memory"; /* soft error - caller \n */
- s = (struct srtbl *)p;
- if (srtold == NULL) { /* empty list */
- ent->srt_top = s;
- srtold = ent->srt_top;
- } else {
- if (i > 0)
- srtold->srt_more = s;
- else
- srtold->srt_less = s;
- }
- s->srt_prev = srtold;
- s->srt_less = NULL;
- s->srt_more = NULL;
- (void) strcpy(s->srt_str, str);
- return NULL;
- }
- SHAR_EOF
- if test 4678 -ne "`wc -c srtunq.c`"
- then
- echo shar: error transmitting srtunq.c '(should have been 4678 characters)'
- fi
- cat << \SHAR_EOF > srtunq.h
- /* include file for memory resident unique sorting routines.
- *
- * Written & hacked by Stephen Uitti, PUCC staff, ach@pucc-j, 1985
- * libsrtunq is copyright (C) Purdue University, 1985
- *
- * Permission is hereby given for its free reproduction and
- * modification for non-commercial purposes, provided that this
- * notice and all embedded copyright notices be retained.
- * Commercial organisations may give away copies as part of their
- * systems provided that they do so without charge, and that they
- * acknowledge the source of the software.
- */
-
- /* database entry */
- struct srtbl {
- struct srtbl *srt_prev; /* parent */
- struct srtbl *srt_less; /* something < srt_str */
- struct srtbl *srt_more; /* something > srt_str */
- char srt_str[1]; /* dynamic: 1 for null at EOS */
- };
-
- /* database tag */
- typedef struct srtent {
- struct srtbl *srt_top; /* root of the tree */
- struct srtbl *srt_next; /* pointer for srtget */
- } SRTUNQ;
-
- /* The functions */
- void srtinit(); /* init for srtin */
- void srtdtree(); /* recursive delete of subtree */
- char *srtin(); /* insert string - return err */
- void srtgti(); /* init for srtgets */
- char *srtgets(); /* get next string */
- void srtfree(); /* free a database */
- SHAR_EOF
- if test 1244 -ne "`wc -c srtunq.h`"
- then
- echo shar: error transmitting srtunq.h '(should have been 1244 characters)'
- fi
- cat << \SHAR_EOF > maketd.sh
- #! /bin/sh
- #
- # maketd - generates file dependencies for makefiles using cc -M
- #
- PATH=/usr/local/bin:/bin:/usr/bin:/usr/ucb
- export PATH
-
- progname=`basename $0`
-
- # Name of the Makefile which will be edited to add the dependencies
- if [ $# = 0 ] ; then
- cat << EOF
- usage: $progname [-a] [-d] [-m<file>] [-o<directory>] [-D...] [-I...] [-U...]
- [<file> ...] [-T <file> ...]
- EOF
- exit
- fi
-
- DEPFILE=/tmp/mtd3$$.tmp
- touch $DEPFILE
- EDDFILE=/tmp/mtd4$$.tmp
-
- trap 'rm -f $DEPFILE $EDDFILE ; exit ' 1 2 3 15
-
- # Default values for -a, -d, -m and -o options
- AOPTION="-e /\/usr\/include/d"
- DOPTION=0
- MAKEFILE=Makefile
- OBJDIR=
-
- # Collect in OPTIONS all options you want to pass on to the C preprocessor.
- # in SOURCES all files you want to create dependencies for
- while [ -n "$1" ] ; do
- case $1 in
-
- -a)
- AOPTION=
- ;;
-
- -d)
- DOPTION=1
- ;;
-
- -m*)
- MAKEFILE=`expr $1 : '-m\(.*\)'`
- ;;
-
- -nonlocalo)
- echo "$progname: -nonlocalo option obsolete"
- exit 1
- ;;
-
- -o*)
- if [ "$1" = "-o" ] ; then
- echo "$progname: -o option requires directory name"
- exit 1
- fi
- OBJDIR=`expr $1 : '-o\(.*\)'`
- if [ ! -d $OBJDIR ] ; then
- echo "$progname: -o option: \"$OBJDIR\" is not a directory"
- exit 1
- fi
- OBJDIR="$OBJDIR/"
- ;;
-
- -[D,I,U]*)
- OPTIONS="$OPTIONS $1"
- ;;
-
- -T)
- shift
- TSOURCES="$*"
- set ""
- ;;
-
- -*)
- echo "$progname: option \"$1\" unknown; ignored"
- ;;
-
- *)
- SOURCES="$SOURCES $1"
- ;;
- esac
- shift
- done
-
- # Run everything through the preprocessor (using cc), sort this
- # output and remove duplictate lines. If there is no '-a' option
- # remove all dependencies of the form '/usr/include/<file>'. Cc
- # will exit quietly if there are no source files.
- /bin/cc -M $OPTIONS $SOURCES | sort | uniq | \
- sed $AOPTION \
- -e "s, \./, ,g" \
- -e "s,\.\./[a-zA-Z0-9]*/\.\.,\.\.,g" \
- -e "s,^,$OBJDIR," >> $DEPFILE
-
- /bin/cc -M $OPTIONS $TSOURCES | sort | uniq | \
- sed $AOPTION \
- -e "s,\.o:,:," \
- -e "s, \./, ,g" \
- -e "s,\.\./[a-zA-Z0-9]*/\.\.,\.\.,g" \
- -e "s,^,$OBJDIR," >> $DEPFILE
-
- # If DOPTION then cat file and exit, otherwise edit Makefile
- if [ $DOPTION -eq 1 ] ; then
- cat $DEPFILE
- rm -f $DEPFILE $EDDFILE
- exit
- fi
-
- # Now start editing the Makefile
- if [ ! -w $MAKEFILE ] ; then
- echo "$progname: can't edit $MAKEFILE"
- rm -f $DEPFILE $EDDFILE
- exit 1
- fi
-
-
- # Make sure we have the "DO NOT DELETE" line in the Makefile
- cat << EOF >> $MAKEFILE
-
- # DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
- EOF
-
- # Build the editor script to edit the Makefile later.
- cat << EOF > $EDDFILE
- /# DO NOT DELETE THIS LINE/,\$d
- \$a
- # DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
- # Dependencies generated at: `date`
-
- EOF
- cat $DEPFILE >> $EDDFILE
- cat << EOF >> $EDDFILE
-
- # DO NOT ADD ANYTHING HERE - WILL GO AWAY
-
-